package com.ywq.thread;

import java.util.concurrent.*;


public class ThreadPoolDemo {
        public static void main(String[] args){
            ExecutorService executorService1 = Executors.newCachedThreadPool();//快
            ExecutorService executorService2 = Executors. newFixedThreadPool(10);//慢
            ExecutorService executorService3 = Executors. newSingleThreadExecutor() ;//最慢
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,20,0l,TimeUnit.MILLISECONDS,new ArrayBlockingQueue<>(10));
            for(int i=1;i<=100;i++) {
                threadPoolExecutor.execute(new MyTask(i));
            }

        }
    /**
     * 项目
     * */

    private static class MyTask implements Runnable {
        int i = 0;

        public MyTask(int i ){
            this.i =i;
        }
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + "做第" + i + "个项目");
            try{
                Thread.sleep(3000L);//业务逻辑 休眠一秒
            } catch ( Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*                  newCachedThreadPool  newFixedThreadPool  newSingleThreadExecutor
底层实现都是      ThreadPoolExecutor
corePoolSize—————————int———————————核心线程数
maximumPoolSize——————int————————————最大线程数
keepAliveTime————————long————————————存活时间
TimeUnit——————————————————————————单位
BlockingQueue/workQueue————————————————————额外存放队列
ThreadFactory threadFactory 线程工厂
RejectExecutionHandler handler 拒绝策略

一、newCachedThreadPool

0 max（2³¹-1）60L SynchronousQueue同步队列

以外包公司为例：
核心员工：corePoolSize=0
非核心员工：max
WorkQueue：同步队列（容量为1）：只能存在一个项目 在队列里等待 被线程执行后才会销毁 再次放一个项目
相当于临时招人,存在一个线程复用



二、newFixedThreadPool
10 10 0 LinkedBlockingQueue
相当于国企
核心员工：10
非核心员工：0
WorkQueue：max（2³¹-1）

100线程与上面效率是否差不多？
是
但根据电脑性能 newFix还是比较快的
不是线程创建越多越好，而是取决于任务的执行时间
根据cpu的核心数  核心线程调度




三、newSingleThreadExecutor
1 1 0 LinkedBlockingQueue
常量
相当于newFix的单一版




阿里员工开发手册 不建议使用自带的线程池工具类

存在  内存溢出   OOM outofmemory

不会出现的是newCached，出现内存溢出情况少
会出现cpu百分百
线程————存储算法——cpu
队列————数据结构————内存

linkedBlockingQueue无界
并行任务过大  队列大 占用内存大  溢出



推荐自定义线程池

提交优先级  核心员工 队列 非核心员工
执行优先级 先执行work   runWork
所以最后输出 11-20这一组

核心员工：10
非核心员工：10
存活时间 0
ArrayBlockingQueue  10


类图
(I)Executor

(I)ExecutorService

(C)  AbstractExecutor      (I)ScheduleExecutor

(C)ThreadPoolExecutor

        (C)ScheduledThreadPoolExecutor


Executor的execute  和ExecutorService的submit方法 区别
都是异步操作
1）
execute无返回值
submit底层调用的execute 但是submit有返回值
2）



execute()
判断 command== null
    throw new NullPointerException();

//提交优先级
      if
        统计 workerCountOf < corePoolSize
        addWorker(command true)



      if(isRunning(c)&& workQueue.offer(command)){
        if  else if双重检测
        检测队列 和 核心线程数是否存满
        else if(!addWorker(command,false))
        //创建非核心的线程 根据一个反方法来判断 如果添加不了就会执行下面代码
            reject(command);
            //一个else if 方法 来执行两个方法
      }
//add() 和 offer()的区别
offer()是add()内部实现
add()四种异常 illegalSateException ClassCastException NullPointerException IllegalArgumentException
add()存满了会抛出一个异常java.lang.IllegalStateException("Queue full")
offer不会抛出异常会返回一个boolean值



 */




































